#!/usr/bin/env bash

_msg() {
    color_off='\033[0m' # Text Reset
    case "${1:-none}" in
    red | error | err) color_on='\033[0;31m' ;;        # Red
    green | info) color_on='\033[0;32m' ;;             # Green
    yellow | warning | warn) color_on='\033[0;33m' ;;  # Yellow
    blue) color_on='\033[0;34m' ;;                     # Blue
    purple | question | ques) color_on='\033[0;35m' ;; # Purple
    cyan) color_on='\033[0;36m' ;;                     # Cyan
    time)
        color_on="[+] $(date +%Y%m%d-%T-%u), "
        color_off=''
        ;;
    stepend)
        color_on="[+] $(date +%Y%m%d-%T-%u), "
        color_off=' ... '
        ;;
    step)
        STEP=$((${STEP:-0} + 1))
        color_on="\033[0;35m[${STEP}] $(date +%Y%m%d-%T-%u), \033[0m"
        color_off=' ... '
        ;;
    *)
        color_on=''
        color_off=''
        need_shift=0
        ;;
    esac
    [ "${need_shift:=1}" -eq 1 ] && shift
    echo -e "${color_on}$*${color_off}"
}

_log() {
    _msg time "$*" | tee -a "$me_log"
}

_check_command(){
    command -v "$@"
}

_check_sudo() {
    [[ "$check_sudo_flag" -eq 1 ]] && return 0
    if [ "$USER" != "root" ]; then
        if sudo -l -U "$USER" | grep -q "ALL"; then
            pre_sudo="sudo"
        else
            echo "User $USER has no permission to execute this script!"
            echo "Please run visudo with root, and set sudo to $USER"
            return 1
        fi
    fi
    if _check_command apt; then
        cmd="$pre_sudo apt"
    elif _check_command yum; then
        cmd="$pre_sudo yum"
    elif _check_command dnf; then
        cmd="$pre_sudo dnf"
    else
        _msg time "not found apt/yum/dnf, exit 1"
        return 1
    fi
    check_sudo_flag=1
}

_check_user(){
    if [[ "$USER" == "root" ]];then
    install_path=/$USER
    else
    install_path=/home/$USER
    fi
}
_check_install_registry() {
    _check_user
    url_git=https://gitee.com/zhangjq1231/install_k8s.git
    if [[ -f "$install_path"/install_k8s/conf/kubernetes.repo && -f "$install_path"/install_k8s/conf/daemon.json ]]; then
        return 0
    else
    ## clone install_k8s or git pull
        git clone -b develop --depth 1 "$url_git" "$install_path"/install_k8s
    fi
}
_check_dependence() {
    _check_install_registry
    _msg step "check command: curl/git/docker"
    _check_command curl || {
        $cmd update
        $cmd install -y curl
    }
    _check_command git || {
        $cmd install -y git zsh
    }
    _check_command strings || $cmd install -y binutils
    ## install docker/compose
    if _check_command docker; then
        return
    fi
    if [[ "$set_sysctl" -eq 1 ]]; then
        echo 'vm.overcommit_memory = 1' | $pre_sudo tee -a /etc/sysctl.conf
    fi
    
    if grep -q -E '^ID=.*openEuler.*' /etc/os-release; then
        $use_sudo curl -fsSL https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo -o /etc/yum.repos.d/docker-ce.repo
        $use_sudo sed -i 's#https://download.docker.com#https://mirrors.tuna.tsinghua.edu.cn/docker-ce#' /etc/yum.repos.d/docker-ce.repo
        $use_sudo sed -i "s#\$releasever#7#g" /etc/yum.repos.d/docker-ce.repo
        $cmd_pkg install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
    else
        if grep -q -E '^ID=.*alinux.*' /etc/os-release; then
            $use_sudo sed -i -e '/^ID=/s/ID=.*/ID=centos/' /etc/os-release
            fake_os=true
        fi
    fi
    if ${aliyun_mirror:-true}; then
        $curl_opt https://gitee.com/zhangjq1231/install_k8s/raw/develop/conf/get-docker.sh | $use_sudo bash -s - --mirror Aliyun
    else
        $curl_opt https://gitee.com/zhangjq1231/install_k8s/raw/develop/conf/get-docker.sh | $use_sudo bash
    fi
    if ! _check_root; then
        _msg time "Add user \"$USER\" to group docker."
        $use_sudo usermod -aG docker "$USER"
        echo '############################################'
        _msg red "!!!! Please logout $USER, and login again. !!!!"
        _msg red "!!!! Please logout $USER, and login again. !!!!"
        _msg red "!!!! Please logout $USER, and login again. !!!!"
        _msg red "And re-execute the above command."
        echo '############################################'
        need_logout=true
    fi

    if [[ "$USER" != ubuntu ]] && id ubuntu; then
        $pre_sudo usermod -aG docker ubuntu
    fi
    if [[ "$USER" != centos ]] && id centos; then
        $pre_sudo usermod -aG docker centos
    fi
    if [[ "$USER" != ops ]] && id ops; then
        $pre_sudo usermod -aG docker ops
    fi
    $pre_sudo systemctl start docker
    $pre_sudo systemctl enable docker
    [[ ${aliyun_os:-0} -eq 1 ]] && $pre_sudo sed -i -e '/^ID=/s/centos/alinux/' /etc/os-release
    
}
_check_timezone() {
    ## change UTC to CST
    _msg step "check timezone "
    if timedatectl | grep -q 'Asia/Shanghai'; then
        _msg time "Timezone is already set to Asia/Shanghai."
    else
        _msg time "Set timezone to Asia/Shanghai."
        $pre_sudo timedatectl set-timezone Asia/Shanghai
    fi
}
_set_docker_daemon(){
     daemon_file=/etc/docker/daemon.json
     if [[ ! -f $daemon_file || ! -s $daemon_file ]];then
         $pre_sudo cp -rf $install_path/install_k8s/conf/daemon.json $daemon_file
     else
         if_cgroupfs=`sudo cat /etc/docker/daemon.json | grep native.cgroupdriver=cgroupfs | wc -l`
         if_systemd=`sudo cat /etc/docker/daemon.json | grep native.cgroupdriver=systemd | wc -l`
         if [[ $if_cgroupfs > 0 ]];then
             sudo sed -i "s/cgroupfs/systemd/g" $daemon_file
         fi
         wc_l=`$pre_sudo cat $daemon_file  | grep -v ^$ | wc -l`
         if [[ $wc_l = 2 ]];then
             $pre_sudo sed -i '1a "exec-opts": ["native.cgroupdriver=systemd"]' $daemon_file
         elif [[ "$wc_l" > 2 && "$if_systemd" == 0 ]];then
             $pre_sudo sed -i '1a "exec-opts": ["native.cgroupdriver=systemd"],' $daemon_file
         fi
     fi
     $pre_sudo systemctl restart docker
}
_swap_off(){
     swap_value=`$pre_sudo free -m | grep Swap | awk '{print $1,$2,$3}'`
     swap_off="0 0 0"
     if [[ $swap_value != $swap_off ]];then
         $pre_sudo swapoff -a
	 $pre_sudo sed -ri 's/.*swap.*/#&/' /etc/fstab
     fi
}
_set_k8s_conf(){
     _swap_off
     _set_docker_daemon
     $pre_sudo sysctl -p $install_path/install_k8s/conf/k8s.conf 
}
_yum_repo(){
     $pre_sudo cp -rf $install_path/install_k8s/conf/kubernetes.repo /etc/yum.repos.d/kubernetes.repo
}
_yum_install_k8s(){
     _yum_repo
     $cmd -y install kubelet-1.23.6 kubeadm-1.23.6 kubectl-1.23.6 --disableexcludes=kubernetes
     $pre_sudo systemctl start kubelet
     $pre_sudo systemctl enable --now kubelet
}
_apt_install_k8s(){
     $cmd update && \
     $cmd -y install curl apt-transport-https 
     $pre_sudo curl -s https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | $pre_sudo apt-key add -  
     $pre_sudo echo "deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main" | $pre_sudo tee /etc/apt/sources.list.d/kubernetes.list
     $cmd update && $cmd -y install kubelet=1.23.6-00 kubeadm=1.23.6-00 kubectl=1.23.6-00 && $pre_sudo apt-mark hold kubelet kubeadm kubectl
     $pre_sudo systemctl start kubelet 
     $pre_sudo systemctl enable kubelet && $pre_sudo systemctl enable --now kubelet
}

_install_k8s(){
     _check_user
     _set_k8s_conf
     _msg time "installing k8s...."
     echo $cmd
     if [[ "$cmd" == "$pre_sudo apt" ]];then
         _msg time"apt install...."
         _apt_install_k8s
	 
     elif [[ "$cmd" == "$pre_sudo yum" ]];then
         _msg time "yum install...."
	     _yum_install_k8s
     fi
}
_check_k8s(){
     if _check_command kubelet || _check_command kubeadm || _check_command kubectl ;then
         _msg yellow "exits installed!!!"
         return
     fi
     _install_k8s
}
_pull_kubeadm_image(){
    IMAGE_VERSION=1.23.6
    images=`kubeadm config images list --kubernetes-version=v${IMAGE_VERSION} | awk -F "/"  '{print $NF}'`
    for i in ${images};do
        docker pull registry.aliyuncs.com/google_containers/$i
    done 
}
_if_node_role(){
    if _check_command kubectl;then
        echo "kubectl installed ...."
    else 
        exit 1
    fi
    read -p "请输入该节点角色(master/node):" role
    if [[ "$role" == "master" ]]; then
	   ##echo "this is master"
	   
	   read -p "是否初始化集群(yes/no) : " init
	   if [[ "$init" == "yes" ]]; then
	       kubeadm reset -f 
	       kubeadm init \
 	 	 --image-repository registry.aliyuncs.com/google_containers \
		 --kubernetes-version v1.23.6 \
		 --pod-network-cidr=10.244.0.0/16 \
		 --service-cidr=10.96.0.0/12 \
	   	 --apiserver-advertise-address=$(hostname -I | awk '{print $1}')
	       mkdir -p $HOME/.kube
	       sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
	       sudo chown $(id -u):$(id -g) $HOME/.kube/config
	       kubectl cluster-info
	   fi
	   
           echo -e "\n"
           
       read -p "master节点是否允许调度资源(yes/no)" master_taint
	   if [[ "$master_taint" == "yes" ]];then
	       taint_master=`kubectl describe node/$(hostname) | grep Taints | awk '{print $2}'`
	       kubectl taint node $(hostname) ${taint_master}-
	   fi

	   read -p "是否自动安装flannel网络插件(yes/no) : " network_plugin
	   if [[ "$network_plugin" == "yes" ]]; then
               kubectl apply -f ./conf/kube-flannel.yml
           fi
	   
           echo -e "\n"

	   read -p "是否自动部署ingress-nginx(yes/no) : " ingress_nginx
	   if [[ "$ingress_nginx" == "yes" ]]; then
	       kubectl apply -f ./conf/ingress-nginx/ingress-deploy.yaml
	       sleep 2
	   fi

           echo -e "\n"

    elif [[ "$role" == "node" ]]; then
	   ##echo "this is node"
	   read -p "是否加入集群(yes/no) : " join_master
	   if [[ "$join_master" == "yes" ]]; then
	   	kubeadm reset -f
	   	read -p "请输入master节点初始化后输出的kuadm join ······ : " join
	   	$join
	   fi
    fi
}
main() {
    curl_opt='curl --connect-timeout 10 -fL'
    _check_sudo
    _check_timezone
    _check_dependence
    _check_k8s
    _pull_kubeadm_image
    _if_node_role
}

main "$@"
